#pragma once
#include<semaphore.h>
#include<vector>
#include"Sem.hpp"
#include"Mutex.hpp"
using namespace SemModule;
using namespace LockModule;
namespace RingBufferModule{
    template<typename T>
    class RingBuffer{
        public:
        RingBuffer(int cap)
        :_c_step(0)
        ,_p_step(0)
        ,_data_sem(0)
        ,_space_sem(cap)
        ,_ring(cap)
        ,_cap(cap)
        {}

        void Pop(T*out){
            _data_sem.P();
            {
            LockGuard lock(_c_lock);
            *out=_ring[_c_step];
            _c_step++;
            _c_step%=_cap;
            }
            _space_sem.V();
        }
        void Equeue(const T&in){
        _space_sem.P();
       { LockGuard lock(_p_lock);
        _ring[_p_step++]=in;
        _p_step%=_cap;
        _data_sem.V();
       }
        pthread_mutex_unlock(&_p_lock);

        }
        ~RingBuffer(){
        }
        private:
        std::vector<T>_ring;
        int _cap;
        int _p_step;
        int _c_step;
        Sem _data_sem;
        Sem _space_sem;
        Mutex _p_lock;
        Mutex _c_lock;

    };
}